#include "Common/TableData/NpcNpcCfg.h"
#include "Common/TableData/MonsterMonsterCfg.h"
#include "Common/TableData/BattlenpcBattlenpcCfg.h"
#include "Common/TableData/SkillSkillCfg.h"
#include "Common/TableData/AiAiCfg.h"
#include "Character/monster/MonsterMgr.h"
#include "Npc.h"
#include "Common/CampDefine.h"
#include "Character/Player.h"

#include "Character/MovePart.h"
#include "Character/SkillPart.h"
#include "Character/PlayerMgr.h"
#include "Common/AttrMgr/AttrMgr.h"

#include "Character/newAI/behaviac/BehaviacAIManager.h"
#include "Character/newAI/behaviac/CreatureCommonAI.h"

#include "Character/monster/MonsterRefMgr.h"
#include "PlaneMgr/PlaneMgr.h"
Npc::Npc() :Monster()
{
	m_creatureKind = CREATURE_NPC;
	m_npcCfgInfo = nullptr;
	m_npcId = 0;
	m_npcIndex = -1;
	m_status = ENUM_NPC_STATUS_NORMAL;
	m_lastPos = Point3<float>();
	m_lastSceneId = 0;
	m_pFacade = nullptr;

	m_sightRange = 25.0f;
	m_viewAngle = 0.0f;
	//m_fspeed = 0.0f;
	m_corpseTime = 0;
	m_battleInfo = nullptr;
}

Npc::~Npc()
{
	
}

void Npc::FindCreatureInScene(Uint64Lst& clist)
{
	//根据提供的坐标位置，找对应场景里的生物
	Scene *pScene = g_GetSceneMgr()->GetScene(m_sceneId);
	if (!pScene)
		return;
	if (m_sightRange <= 0)
		return;

	pScene->FindCreatureInScene(clist, m_pos, m_sightRange);
}


//根据配置的公式算出该怪物属性值
//uint64_t Npc::GetMonsterAttrFormula(std::string str)
//{
//	VEC_INT32 outPara;
//	GetFormula(str, outPara);
//	if (outPara.size()==0)
//	{
//		return 0;
//	}
//	else if (outPara.size() == 1)
//	{
//		return outPara[0];
//	}
//	else
//	{
//		if (outPara[0]== 1) //是公式1
//		{
//			if (outPara.size()!=4)
//			{
//				LogErrFmtPrint("monster attr formula error str=%s",str.c_str());
//				return 0;
//			}
//			return m_attrs[M_LEVEL]  * m_attrs[M_LEVEL]*outPara[1] / 100.0 + outPara[2]/100.0 * m_attrs[M_LEVEL] + outPara[3]/100.0;
//		}
//	}
//	return 0;
//}

//获取怪物模型半径
float Npc::GetModelRadius()
{
	if (!m_npcCfgInfo || !m_battleInfo)
	{
		return 0;
	}
	return (float)m_battleInfo->modelRadius / 1000.0f * m_modelScale.x;
}

bool Npc::Init()
{
	memset(m_attrs, 0, sizeof(uint32_t)*M_MAX);
	memset(m_attrs64, 0, sizeof(uint64_t)*M_ATTR_ULONG_END);

	for (size_t i = 0; i < PART_MAX; i++)
	{
		m_pPart[i] = nullptr;
	}

	m_npcCfgInfo = g_GetNpcNpcCfgTable()->GetNpcNpcCfgInfo(m_npcId);
	if (m_npcCfgInfo == nullptr)
	{
		LogErrFmtPrint("[logic] Npc::Init m_npcCfgInfo == nullptr....m_npcId:%u ", m_npcId);
		return false;
	}

	const BattlenpcBattlenpcCfgInfo *pBattleInfo = g_GetBattlenpcBattlenpcCfgTable()->GetBattlenpcBattlenpcCfgInfo(m_npcCfgInfo->linkBattlenpc);
	if (pBattleInfo)
	{
		m_battleInfo = pBattleInfo;
		//m_attrs[M_LEVEL] = pBattleInfo->npcLV;


		stNpcConfig * pNpcParam = g_GetMonsterMgr()->GetBattleNpcConfigParam(pBattleInfo->ID);
		if (!pNpcParam)
		{
			LogErrFmtPrint("[logic] Npc::Init find npc error npcid = %u, battleid:%u ", m_npcId, pBattleInfo->ID);
			return false;
		}

		m_attrs64[M_MAX_HP] = GetMonsterAttrFormula(pNpcParam->_maxHP);

		if (pBattleInfo->hpSectionNum > 1)
		{
			m_attrs64[M_MAX_HP] = m_attrs64[M_MAX_HP] * pBattleInfo->hpSectionNum;
		}
		m_attrs64[M_HP] = m_attrs64[M_MAX_HP];

		m_attrs[M_MP] = GetMonsterAttrFormula(pNpcParam->_maxMP);
		m_attrs[M_MAX_MP] = GetMonsterAttrFormula(pNpcParam->_maxMP);
		SetAttrMA(M_LEVEL, pBattleInfo->npcLV);
		SetAttrMA(g_GetAttrMgr()->GetMonsterLevMNumAttr(C_AP), GetMonsterAttrFormula(pNpcParam->_ap));
		SetAttrMA(g_GetAttrMgr()->GetMonsterLevMNumAttr(C_MAT), GetMonsterAttrFormula(pNpcParam->_mat));
		SetAttrMA(g_GetAttrMgr()->GetMonsterLevMNumAttr(C_DP), GetMonsterAttrFormula(pNpcParam->_dp));
		SetAttrMA(g_GetAttrMgr()->GetMonsterLevMNumAttr(C_MDP), GetMonsterAttrFormula(pNpcParam->_mdp));
		SetAttrMA(g_GetAttrMgr()->GetMonsterLevMNumAttr(C_PHYHIT), GetMonsterAttrFormula(pNpcParam->_phyHit));
		SetAttrMA(g_GetAttrMgr()->GetMonsterLevMNumAttr(C_MAGHIT), GetMonsterAttrFormula(pNpcParam->_magHit));
		SetAttrMA(g_GetAttrMgr()->GetMonsterLevMNumAttr(M_PHYDODGE), GetMonsterAttrFormula(pNpcParam->_phyDodge));
		SetAttrMA(g_GetAttrMgr()->GetMonsterLevMNumAttr(C_MAGDODGE), GetMonsterAttrFormula(pNpcParam->_magDodge));
		SetAttrMA(g_GetAttrMgr()->GetMonsterLevMNumAttr(C_PHYCRIT), GetMonsterAttrFormula(pNpcParam->_phyCrit));
		SetAttrMA(g_GetAttrMgr()->GetMonsterLevMNumAttr(C_MAGCRIT), GetMonsterAttrFormula(pNpcParam->_magCrit));
		SetAttrMA(g_GetAttrMgr()->GetMonsterLevMNumAttr(C_PHYTOUGHNESS), GetMonsterAttrFormula(pNpcParam->_phyToughness));
		SetAttrMA(g_GetAttrMgr()->GetMonsterLevMNumAttr(C_MAGTOUGHNESS), GetMonsterAttrFormula(pNpcParam->_magToughness));
		SetAttrMA(g_GetAttrMgr()->GetMonsterLevMNumAttr(C_FIREDEF), GetMonsterAttrFormula(pNpcParam->_fireDef));
		SetAttrMA(g_GetAttrMgr()->GetMonsterLevMNumAttr(C_ICEDEF), GetMonsterAttrFormula(pNpcParam->_iceDef));

		SetAttrMA(g_GetAttrMgr()->GetMonsterLevMNumAttr(C_WINDDEF), GetMonsterAttrFormula(pNpcParam->_windDef));
		SetAttrMA(g_GetAttrMgr()->GetMonsterLevMNumAttr(C_SOLDEF), GetMonsterAttrFormula(pNpcParam->_solDef));
		SetAttrMA(g_GetAttrMgr()->GetMonsterLevMNumAttr(C_RAYDEF), GetMonsterAttrFormula(pNpcParam->_rayDef));
		SetAttrMA(g_GetAttrMgr()->GetMonsterLevMNumAttr(C_POISONDEF), GetMonsterAttrFormula(pNpcParam->_poisonDef));
		SetAttrMA(g_GetAttrMgr()->GetMonsterLevMNumAttr(C_PHYCRITMUL), GetMonsterAttrFormula(pNpcParam->_phyCritMul));
		SetAttrMA(g_GetAttrMgr()->GetMonsterLevMNumAttr(C_MAGCRITMUL), GetMonsterAttrFormula(pNpcParam->_magCritMul));
		//m_attrs[M_MSPEED] = pBattleInfo->mSpeed;

		//m_fspeed = pBattleInfo->mSpeed / 1000.0f;

		SetAttrMA(g_GetAttrMgr()->GetMonsterLevMNumAttr(C_MSPEED), pBattleInfo->mSpeed, false);

		if (pBattleInfo->viewType == ENUM_MONSTER_VIEW_TYPE_CIRCLE ||
				pBattleInfo->viewType == ENUM_MONSTER_VIEW_TYPE_BALL)
		{
			if (pNpcParam->_view.size()<1)
			{
				LogDebugFmtPrint("npc view error id=%d",m_npcId);
				return false;
			}
			m_sightRange = pNpcParam->_view[0] / 1000.0f;
			if (pBattleInfo->pursueRange < m_sightRange*1000)
			{
				LogErrFmtPrint("the npcId:%d sight range > purse range", m_npcId);
			}
		}
		else if (pBattleInfo->viewType == ENUM_MONSTER_VIEW_TYPE_SECTOR)
		{
			//std::vector<std::string> vec;
			//CommonApi::SplitStr(pBattleInfo->view.c_str(), ",", &vec);

			if (pNpcParam->_view.size() != 2)
			{
				m_sightRange = 25.0f;//
			}
			else
			{
				m_sightRange = pNpcParam->_view[0] / 1000.0f;
				m_viewAngle = pNpcParam->_view[1];
			}
		}
	}

	//初始化怪物部件
	m_pPart[PART_MOVE] = g_GetCreatureMgr()->CreatePart(PART_MOVE, dynamic_cast<Creature*>(this));
	if (!m_pPart[PART_MOVE])
		return false;
	m_pPart[PART_SKILL] = g_GetCreatureMgr()->CreatePart(PART_SKILL, dynamic_cast<Creature*>(this));
	if (!m_pPart[PART_SKILL])
		return false;
	m_pPart[PART_BUFF] = g_GetCreatureMgr()->CreatePart(PART_BUFF, dynamic_cast<Creature*>(this));
	if (!m_pPart[PART_BUFF])
		return false;

	//注册被击事件
	g_GetEvent()->Subscribe(this, EVENT_UNDER_ATTACK,m_Cid,0,"npc register attack event");
	g_GetEvent()->Subscribe(this, EVENT_ATTACK_SOMEBODY,m_Cid,0,"npc register attack event");

	if (pBattleInfo)
	{
		std::vector<int32_t> vecNormalSkill;
		CommonApi::SplitStrToVecInt(pBattleInfo->normalSkill, ",", &vecNormalSkill);

		//初始化怪物的技能属性
		SkillPart* pSkillPart = static_cast<SkillPart*>(GetPart(PART_SKILL));
		if (pSkillPart == nullptr)
			return false;

		for(int i = 0; i < (int)vecNormalSkill.size(); i++)
		{
			const SkillSkillCfgInfo *pInfo = g_GetSkillSkillCfgTable()->GetSkillSkillCfgInfo(vecNormalSkill[i]);
			if (pInfo != nullptr)
			{
				pSkillPart->AddSkill(pInfo->skillID, 1, 0,0,false,false);
			}
		}

		const AiAiCfgInfo *pInfo = g_GetAiAiCfgTable()->GetAiAiCfgInfo(pBattleInfo->specialAI);
		if (pInfo)
		{
			std::vector<int> initSkill;
			CommonApi::SplitStrToVecInt(pInfo->initSkills, ",", &initSkill);
			if (initSkill.size() > 0 && initSkill.size() % 3 == 0)
			{
				for (uint32_t i = 0; i < initSkill.size(); i+=3)
				{
					int skillId = initSkill[i];
					int priority = initSkill[i + 1];
					int time = initSkill[i+2];
					pSkillPart->AddSkill(skillId, 1, 0, priority,false,false);
					stSkillInfo* pSkillInfo = pSkillPart->GetSkillInfo(skillId);
					if (pSkillInfo)
					{
						pSkillInfo->_cdTimeStamps = Time::Now().UnixMSec() - pSkillInfo->_pSkillmeta->cd + time;
					}
				}
			}
		}

		m_aiData = g_GetBehaviacAIMgr()->CreateAI("AI_NPC_00", m_Cid);

		if (m_aiData)
		{
			m_aiData->Init(this);
			m_aiData->SetAiEnable(true);
		}
	}

	return true;
}

bool Npc::UnInit()
{
	memset(m_attrs, 0, sizeof(uint32_t)*M_MAX);

	for (int32_t i = 0; i < PART_MAX; i++)
	{
		if (m_pPart[i])
		{
			g_GetCreatureMgr()->RecylePart(m_pPart[i]);
			m_pPart[i] = nullptr;
		}
	}

	g_GetEvent()->UnSubscribe(this, EVENT_UNDER_ATTACK, m_Cid, 0);
	g_GetEvent()->UnSubscribe(this, EVENT_ATTACK_SOMEBODY, m_Cid, 0);
	g_GetTimerAxis()->KillAllTimer(this);

	if (m_pFacade)
	{
		delete m_pFacade;
		m_pFacade = nullptr;
	}

	m_npcCfgInfo = nullptr;
	//LeaveScene();
	g_GetGeneralCreatureRefMgr()->npcDead(m_sceneId, m_Cid);
	Creature::UnInit();

	//销毁npc,一般只有在销毁场景时处理，这里打印下npc的配置ID，以便查看
	//LogErrFmtPrint("destory npc npcid=%d,cid=%llu,m_sceneid=%d", m_npcId, m_Cid, m_sceneId);

	return true;
}

bool Npc::Born(CharIDType npcCid, uint32_t npcId, uint32_t sceneId, Point3<float>& bornPos, int32_t npcIdx/* = -1*/)
{
	m_Cid = npcCid;
	m_npcId = npcId;
	m_bornPos = bornPos;
	m_npcIndex = npcIdx;

	bool ret = Init();
	if (ret == false)
	{
		return false;
	}

	if (InitConfig(m_npcId) == false)
	{
		return false;
	}
	STransParam transParam;
	transParam.transType = ETransType_Born;
	if (!EnterScene(sceneId, bornPos, transParam))
	{
		LogErrFmtPrint("[logic] Npc::Born...npcid:%u, cid:%llu, sceneid:%u, ",m_npcId,m_Cid,sceneId);
		return false;
	}
	return true;
}

void Npc::AddSeeNewCreature(Creature* pCreature)
{
	if (IsDead())
	{
		return;
	}

	if (pCreature->CreatureKind() == CREATURE_PLAYER
			|| pCreature->CreatureKind() == CREATURE_NPC
			|| pCreature->CreatureKind() == CREATURE_MONSTER)
	{
		if (!IsFriendSide(pCreature))
		{
			if (m_aiData)
			{
				if (m_aiData->GetNpcTeamId() > 0)
				{
					if (m_aiData->IsNpcTeamLeader())
					{
						if (!pCreature->HasBuffState(CREATURE_BUFF_STATE_INVISIBLE))
						{
							m_aiData->AddHateTarget(pCreature->GetCid(), 0, 0);
							//g_GetCreatureMgr()->NpcTeamSyncHate(this->GetBattleInfo()->npcTeam, this, pCreature->GetCid(), 0);
						}
					}
					return;
				}

				if (pCreature->HasBuffState(CREATURE_BUFF_STATE_INVISIBLE))
				{
					if (HasBuffState(CREATURE_BUFF_STATE_SEEINVISIBLE))
					{
						m_aiData->AddHateTarget(pCreature->GetCid(), 0, 0);
					}
				}
				else
				{
					m_aiData->AddHateTarget(pCreature->GetCid(), 0, 0);
				}
			}
		}
	}
}

void Npc::Update(uint64_t tick)
{
	//怪物没有死才做update操作
	if (!IsDead())
	{
		Creature::Update(tick);

		//部件update
		for (int32_t i = 0; i < PART_MAX; i++)
		{
			if (m_pPart[i])
				m_pPart[i]->Update(tick);
		}

		UpdateAiInfo(tick);
	}
}

void Npc::OnCorpse()
{

	//怪物尸体时间到了 表示可以从场景移除 并且需要设置以下生物的destory标记
	//CreatureMgr会读取生物的destory标记进行做内存回收操作 MonsterMgr不需要管内存回收
	if (LeaveScene())
	{
		//下一帧准备等待回收
		//g_GetCreatureMgr()->WaitDestory(GetCid());
		g_GetCreatureMgr()->WaitDestory((Creature*)this);
	}
}

bool Npc::IsInCorpseTime()
{
	return m_corpseTime > g_GetGlobalServerTime()->Tick();
}

void Npc::OnDead(CharIDType killerCid)
{
	if (!IsDead())
	{
		g_GetEvent()->FireExecute(EVENT_CREATURE_WILLING_DIED, m_Cid, 0, nullptr, 0);
		if (GetAttr(C_HP) > 0)
		{
			return;
		}

		StopMove(false);

		//OnDoEffect(false);  //置死亡状态前，先处理这个效果

		BuffEffect_CleanupAllFadeOutEffects(BuffInfoDeadEnd);

		Creature::OnDead(killerCid);

		DieEvent dieEvent;
		dieEvent.killerCid = killerCid;
		dieEvent.count = 1;
		dieEvent.sceneId = m_sceneId;
		dieEvent.nCid = m_Cid;
		dieEvent.monsterId = GetConfigId();
		//dieEvent.dropOwnerCid = m_dropOwnerID;
		dieEvent.planUid = GetPlaneID();
		//获取该怪物仇恨列表的人
		//dieEvent.hateTargetList = GetMonsterKillerList();
		g_GetEvent()->FireExecute(EVENT_CREATURE_DEAD, killerCid, m_creatureKind, (DieEvent*)&dieEvent, sizeof(dieEvent));

		//后面判断是否有尸体时间
		if (GetBattleInfo())
		{
			if (GetBattleInfo()->npcTeam > 0)
			{
				g_GetCreatureMgr()->NpcTeamDelNpc(GetSceneId(), GetBattleInfo()->npcTeam, this);
			}
			m_corpseTime = g_GetGlobalServerTime()->Tick() + GetBattleInfo()->bodyStayTime;
			g_GetTimerAxis()->SetTimer(enTimeID_CorpseTime, GetBattleInfo()->bodyStayTime, this, 1);
		}
		//CTODO 要考虑生物死亡后是否要将生物各个部件的定时器进行清除操作 这个应该要放到死亡做
	}
}

void Npc::OnTimer(uint32_t nTimerID)
{
	switch (nTimerID)
	{
	case enTimeID_CorpseTime:
	{
		OnCorpse();
	}
	break;
	default:
		break;
	}

}

void Npc::GetVisibleDataToClient(CreaturesCreateData& cvData)
{
	CreaturesCreateData::Npc *pNpcData = cvData.add_npcs();
	pNpcData->set_npcconfigid(m_npcId);
	pNpcData->set_posx(m_pos.x);
	pNpcData->set_posy(m_pos.y);
	pNpcData->set_posz(m_pos.z);
	pNpcData->set_npccid(m_Cid);
	pNpcData->set_npc_idx(m_npcIndex);
	if (m_pFacade)
	{
		CharOutward * pFacade=pNpcData->mutable_facade();
		pFacade->CopyFrom(*m_pFacade);
	}
	pNpcData->set_currenthp(m_attrs64[M_HP]);
	pNpcData->set_maxhp(m_attrs64[M_MAX_HP]);
	pNpcData->set_level(m_attrs[M_LEVEL]);
	pNpcData->set_mspeed(m_attrs[M_MSPEED]/1000.0f);
	MovePart * pPart = dynamic_cast<MovePart*>(m_pPart[PART_MOVE]);
	if (pPart)
	{
		ActorMove actormove;
		ActorRockerMove rockmove;
		pPart->GetMoveingState(actormove, rockmove);
		if (pPart->GetMoveFlag() == enMovingFlag_Mouse)
		{
			ActorMove *pActormove = pNpcData->mutable_actormove();
			pActormove->CopyFrom(actormove);
		}
	}

	BuffPart * pBuffPart = dynamic_cast<BuffPart*>(m_pPart[PART_BUFF]);
	if (pBuffPart)
	{
		msgBuffList * pList = pNpcData->mutable_bufflist();
		pBuffPart->GetAllBuffInfo(pList);
	}
}

bool Npc::InitConfig(uint32_t npcId)
{
	m_npcCfgInfo = g_GetNpcNpcCfgTable()->GetNpcNpcCfgInfo(npcId);
	if (m_npcCfgInfo)
	{
//		if (m_npcCfgInfo->npcFightType == 1 && m_npcCfgInfo->linkMonster != 0)
//		{
//			if (g_GetMonsterMonsterCfgTable()->GetMonsterMonsterCfgInfo(m_npcCfgInfo->linkMonster) == nullptr)
//			{
//				LogErrFmtPrint("in the npc cfg table npc id :%d can't find the link monster id:%d", npcId, m_npcCfgInfo->linkMonster);
//			}
//		}

		return true;
	}
	return false;
}

const NpcNpcCfgInfo* Npc::GetNpcInfo() const
{
	return m_npcCfgInfo;
}

const BattlenpcBattlenpcCfgInfo *Npc::GetBattleInfo() const
{
	return m_battleInfo;
}

uint32_t Npc::GetConfigId() const
{
	return m_npcId;
}

bool  Npc::IsFunctionType() const
{
	return m_npcCfgInfo->isFunctionNPC == 1;
}

bool  Npc::IsFightType() const
{
	return m_npcCfgInfo->npcFightType == 1;
}

uint32_t Npc::GetNpcCamp() const
{
	return m_npcCfgInfo->npcCamp;
}

uint32_t Npc::GetLinkMonsterId() const
{
	return m_npcCfgInfo->linkMonster;
}

bool Npc::IsFriendSide(Creature* pCreature)
{
	if (pCreature == nullptr || pCreature == this || pCreature->IsDead())
	{
		return true;
	}

	if (pCreature->HasBuffState(CREATURE_BUFF_STATE_WUDI))
	{
		return true;
	}

	if (this->GetNpcInfo()->npcFightType == 0)
	{
		return true;
	}

	if (pCreature->CreatureKind() != CREATURE_PLAYER
		&& pCreature->CreatureKind() != CREATURE_MONSTER
		&& pCreature->CreatureKind() != CREATURE_REBOT
		&& pCreature->CreatureKind() != CREATURE_NPC)
	{
		return true;
	}

	Npc* pNpc = dynamic_cast<Npc*>(pCreature);
	if (pNpc && pNpc->GetNpcInfo()->npcFightType == 0)
	{
		return true;
	}

	if (GetNpcCamp() == ECamp_Type_None)
	{
		if (pCreature->CreatureKind() == CREATURE_PLAYER)
		{
			Player* pPlayer = dynamic_cast<Player*>(pCreature);
			if (pPlayer && !pPlayer->IsDead())
			{
				if (pPlayer->GetAttr(C_CAMP_ID) == ECamp_Type_None)
				{
					if (pPlayer->GetPkKillingValue() >= 3)
					{
						return false;
					}
				}
				else
				{
					if (pPlayer->GetPkKillingValue() >= 10)
					{
						return false;
					}
				}
			}
		}
		return true;
	}
	else
	{
		if (pCreature->CreatureKind() == CREATURE_PLAYER)
		{
			Player* pPlayer = dynamic_cast<Player*>(pCreature);
			if (pPlayer && !pPlayer->IsDead())
			{
				if (pPlayer->GetPkKillingValue() >= 3)
				{
					return false;
				}
			}
		}	//如果对方是一直召唤物，如果对方不可被攻击，返回true, 如果主人存在就 依据主人
		else if (pCreature->CreatureKind()== CREATURE_NPC)
		{
			Npc* pNpc = dynamic_cast<Npc*>(pCreature);
			if (pNpc && pNpc->GetNpcInfo()->npcFightType == 0)
			{
				return true;
			}
		}
		else if (pCreature->CreatureKind() == CREATURE_MONSTER)
		{
			Monster* pMonster = dynamic_cast<Monster*>(pCreature);
			if (pMonster)
			{
				if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_SUMMON)
				{
					if (pMonster->GetMonsterMasterCID() == GetCid())
					{
						return true;
					}
					//如果对方不可被攻击，返回true
					if (pMonster->GetMonsterFightType() == SUMMON_MONSTER_TYPE_CANNOT_BEATTACK_CANNOT_MOVE
							|| pMonster->GetMonsterFightType() == SUMMON_MONSTER_TYPE_CANNOT_BEATTACK_CAN_MOVE)
					{
						return true;
					}

					if (pMonster->GetMonsterMasterKind() == CREATURE_PLAYER)
					{
						//如果主人存在就 依据主人
						Creature* pOwner = GetScene()->GetCreature(pMonster->GetMonsterMasterCID());
						if (pOwner && pOwner != this)
						{
							return IsFriendSide(pOwner);
						}
					}
				}
				else if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_MOVE_BIAOCHE
						|| pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_MOVE_TEAM_BIAOCHE)
				{
					return true;
				}
				else if (pMonster->GetParentMonsterType() == PARENT_MONSTER_TYPE_MOVE_BIAOCHE_MONSTER)
				{
					return true;
				}
			}
		}
	}

	//通过表格探寻其他关系
	int first = gGetCreatureFriendShip(this);
	int second = gGetCreatureFriendShip(pCreature);
	return gGetCreatureVsCreature(first, second);
}

Point3<float> Npc::GetBornPos() const
{
	return m_bornPos;
}

uint32_t Npc::GetStatus() const
{
	return m_status;
}

void Npc::SetStatus(uint32_t status)
{
	m_status = status;
}


void Npc::SetFacade(const CharOutward & value)
{
	if (!m_pFacade)
	{
		m_pFacade = new CharOutward();
	}
	m_pFacade->CopyFrom(value);
}

void Npc::DeleteFacade()
{
	if (m_pFacade)
	{
		delete m_pFacade;
		m_pFacade = NULL;
	}
}

//bool Npc::AddAttr(uint32_t CANum, int64_t attrValue, bool syn, uint64_t relationCid /* = 0 */)
//{
//	uint32_t MANum = GetAttrNum(CANum);
//	if (MANum == M_NONE || MANum > M_MAX)
//	{
//		//错误打印，访问怪物没有的属性
//		LogErrFmtPrint("Monster::AddAttr error %d", CANum);
//		return false;
//	}
//
//	return AddAttrMA(MANum, attrValue, syn, relationCid);
//}
//
//bool  Npc::AddAttrMA(uint32_t MANum, int64_t attrValue, bool syn, uint64_t relationCid/* = 0*/)
//{
//	if (MANum == M_NONE || MANum >= M_MAX)
//	{
//		return false;
//	}
//
//	//生命值类的护盾处理
//	if (MANum == M_HP && attrValue < 0)
//	{
//		BuffEffect_CleanupAllFadeOutEffects(BuffInfoBeDamagedEnd);
//	}
//
//	if (attrValue == 0)
//		return false;
//
//	if (MANum>M_ATTR_ULONG_END)
//	{
//		//防止溢出
//		if (attrValue < 0)
//		{
//			uint32_t absValue = abs(attrValue);
//			m_attrs[MANum] = ((m_attrs[MANum] > absValue) ? (m_attrs[MANum] - absValue) : 0);
//		}
//		else
//		{
//			//
//			m_attrs[MANum] = m_attrs[MANum] + (uint32_t)attrValue;
//		}
//	}
//	else
//	{
//		//防止溢出
//		if (attrValue < 0)
//		{
//			uint64_t absValue = abs(attrValue);
//			m_attrs64[MANum] = ((m_attrs64[MANum] > absValue) ? (m_attrs64[MANum] - absValue) : 0);
//		}
//		else
//		{
//			//
//			m_attrs64[MANum] = m_attrs64[MANum] + (uint64_t)attrValue;
//		}
//	}
//
//
//	if (MANum == M_HP && m_attrs64[MANum] == 0)
//	{
//		OnDead(relationCid);
//	}
//
//	//影响其他属性公式
//	AttrsFormula(MANum, relationCid, syn);
//	if (syn)
//	{
//		SynAttrCache(MANum);
//		SynAttrToClient();
//	}
//
//	return true;
//}
//
//void Npc::SetAttrCache(uint32_t CANum, int64_t attrValue)
//{
//
//}
//
//bool Npc::AddAttrCache(uint32_t CANum, int64_t attrValue, uint64_t relationCid)
//{
//	return true;
//}
//
//void Npc::SetAttr(uint32_t CANum, int64_t attrValue, bool syn /* = false */)
//{
//	uint32_t MANum = GetAttrNum(CANum);
//	SetAttrMA(MANum, attrValue, syn);
//	return;
//}
//
//void  Npc::SetAttrMA(uint32_t MANum, int64_t attrValue, bool syn/* = false*/)
//{
//	if (MANum == M_NONE || MANum > M_MAX || attrValue < 0)
//	{
//		return;
//	}
//
//	m_attrs[MANum] = attrValue > 0 ? attrValue : 0;
//
//	AttrsFormula(MANum, 0, syn);
//
//	if (MANum == M_HP && m_attrs[MANum] == 0)
//	{
//		syn = true;  //如果是血量，且达到了死亡状态 ，则时实同步
//		OnDead(m_Cid);
//		LogErrFmtPrint("er::SetAttrMA  someone sethp=0, error cid= %d", m_Cid);
//	}
//
//
//	if (syn && MANum<M_USE_ATTR_END)
//	{
//		SynAttrCache(MANum);
//		SynAttrToClient();
//	}
//}
//
//int64_t Npc::GetAttr(uint32_t CANum)
//{
//	uint32_t MANum = GetAttrNum(CANum);
//	if (MANum == M_NONE || MANum >= M_MAX)
//	{
//		//错误打印，访问怪物没有的属性
//		//LogErrFmtPrint("Monster::GetAttr error %d", CANum);
//		return M_NONE;
//	}
//	if (MANum>M_ATTR_ULONG_END)
//	{
//		return m_attrs[MANum];
//	}
//	else
//	{
//		return m_attrs64[MANum];
//	}
//}
//
//uint32_t Npc::GetAttrNum(uint32_t CommonAttrNum)
//{
//	return g_GetAttrMgr()->GetMAttr(CommonAttrNum);
//}
//
//bool  Npc::AttrsFormula(uint32_t MANum, uint64_t relationCid, bool cache)
//{
//
//	if (MANum < M_USE_ATTR_END)
//	{
//		//基础属性进来，都是已加好的，不用再执行加法
//		return false;
//	}
//
//	AttrMgr::VecAttr *pVecMap = g_GetAttrMgr()->GetMAddAttrsFormula(MANum);
//	if (!pVecMap || pVecMap->size() < 2)
//		return false;
//
//	AttrMgr::VecAttr& vecMap = *pVecMap;
//
//	int64_t value = 0;
//
//	//有几个属性，以前是直接操作的，为了改动尽量小，这里也直接操作，不用加法处理了
//	//以前的处理方式是将需要用到加法的都注册 ，这里 是所有的都注册 ，然后不用的去掉。
//	if (vecMap[0] == M_HP ||
//		vecMap[0] == M_MP)
//	{
//		return false;
//	}
//
//
//	for (uint32_t i = 1; i < vecMap.size(); i++)
//		value += m_attrs[vecMap[i]];
//
//	if (value < 0)
//		LogErrFmtPrint("value cannt < 0, error key:%d", MANum);
//
//
//	//只缓存，同步客户端在外层处理
//
//	SetAttrMA(vecMap[0], value,true);
//
//	return true;
//}
//
//void  Npc::SynAttrCache(uint32_t MANum)
//{
//	if (MANum == M_NONE || MANum >= M_MAX)
//	{
//		return;
//	}
//
//	if (g_GetAttrMgr()->IsBroadcastMAttr(MANum))
//	{
//		/*
//		ProtoBuf::Attr* pAttr = m_attrBroadcastClient.add_creatureattrs();
//		pAttr->set_attrnum(MANum);
//		pAttr->set_attrvalue(m_attrs[MANum]);
//		*/
//		if (MANum>M_ATTR_ULONG_END)
//		{
//			m_attrsBroadCastCache[MANum] = m_attrs[MANum];
//		}
//		else
//		{
//			m_attrs64BroadCastCache[MANum] = m_attrs[MANum];
//		}
//	}
//}

void Npc::OnExecute(uint16_t nEventID, uint64_t nSrcID, uint8_t bySrcType, void *pContext, int32_t nLen)
{
	switch (nEventID)
	{
	case EVENT_ATTACK_SOMEBODY:
	{
	}
	break;
	case EVENT_UNDER_ATTACK:  //自已的被击事件
	{
	}
		break;
	default:
		break;
	}
}

bool Npc::ViewFliter(Creature* pCreature, float dict)
{

	if (m_npcCfgInfo && m_npcCfgInfo->npcType == 1)
	{
		if (pCreature->GetPlaneID()<=0)
		{
			return true;
		}
	}

	return Monster::ViewFliter(pCreature, dict);
}
